<?php
/**
 * Crmlite_View_Helper_Pagination
 *
 * @final
 * @package Crmlite_App
 * @version $Id: Pagination.php 28 2007-08-30 04:15:14Z etng2004 $
 * @copyright 2006-2007 ETE.CN
 * @author Yi BO  <etng2004@gmail.com>
 * @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
 */
class Crmlite_View_Helper_Pagination
{

	private static $styles = array(
	'default'	=> array(
					'summary'	=> '<li><span class="info">%{record_count} 条记录，共 %{page_count} 页，第 %{current} 页，每页 %{perpage} 条</span></li>',
					'first'		=> '<li><a href="%{_url}"><span>|&lt;</span></a></li>',
					'last'		=> '<li><a href="%{_url}"><span>&gt;|</span></a></li>',
					'previous'	=> '<li><a href="%{_url}"><span>&lt;&lt;</span></a></li>',
					'next'		=> '<li><a href="%{_url}"><span>&gt;&gt;</span></a></li>',
					'page'		=> '<li><a href="%{_url}"><span>%{_text}</span></a></li>',
					'current'	=> '<li><span>%{_text}</span></li>',
					'result'	=> '<div  class="pager"><ul>%{summary}%{first}%{previous}%{pages}%{next}%{last}</ul></div>',
					'delimeter'	=> "\n",
	),
	);
    private static $style = 'default';
    private static $perpage = 20;
    private static $persection = 10;

    public static $_params = array();

    /**
     * view
     *
     * @var Zend_View_Interface
     * @access public
     */
    public $view;

    /**
     * setView
     *
     * @param Zend_View_Interface $view
     * @access public
     * @return Zend_View_Interface
     */
    public function setView(Zend_View_Interface $view)
    {
        $this->view = $view;
        return $this->view;
    }

	/**
	 * 主要调用函数，验证分页参数并返回分页内容
	 *
	 * @param int $total		总记录数
	 * @param int $current		当前页
	 * @param int $perpage		每页记录数
	 * @param int $persection	每个分页条显示页码数
	 * @param string $style		分页样式
	 * @return string
	 */
    public function pagination($total, $current = 1, $perpage = null, $persection = null, $style = null)
    {
        $params = $this->_verifyParam($total, $current, $perpage, $persection);
        return $this->_buildPaginBar($params);
    }
	/**
	 * 设置分页显示默认样式
	 *
	 * 如果存在则设置，否则保持原判
	 *
	 * @param string $style
	 * @return string
	 */
    public static function setDefaultStyle($style)
    {
		if(array_key_exists($style, self::$styles))
		{
			self::$style = $style;
		}
		return self::$style;
    }

	/**
	 * 设置分页显示默认数据
	 *
	 * @param int $perpage
	 * @param int $persection
	 * @return unknown
	 */
    public static function setParam($perpage = null, $persection = null)
    {
    	if(intval($perpage)>0)self::$perpage = $perpage;
    	if(intval($persection)>0)self::$persection = $persection;
    }

    /**
     * 增加分页显示样式
     *
     * @param string $name		样式名称
     * @param array $style		样式定义数组
     * @param bool $isDefault	设为默认样式否
     * @return string
     */
    public static function addStyle($name, $style, $isDefault = true)
    {
    	self::$styles[$name] = $style;
		return $isDefault?self::setDefaultStyle($name):self::$style;
    }
	/**
	 * 验证数据正确性，并设置正确的分页区间
	 *
	 * @param int $total
	 * @param int $current
	 * @param int $perpage
	 * @param int $persection
	 * @return array
	 * @todo 实现按段分的功能
	 */
    protected function _verifyParam($total, $current = 1, $perpage = 20, $persection = 10)
    {
    	$record_count = $total;
        $perpage 	= ($perpage <= 0) ? self::$perpage : $perpage;
        $persection = ($persection <= 0) ? self::$persection : $persection;
        $perside 	= ceil($persection / 2);
        $page_count = ceil($total / $perpage);
        $current 	= ($current <= 0) ? 1 : $current;
        $current 	= ($current > $page_count) ? $current : $current;
        /**
         * 注意，这里的是上一段，下一段，而不是上一页下一页,同时也可以作为起始和终止的页码数
         */
        $previous 	= ($current - $perside) < 1 ? 1 : $current - $perside;
        $next 		= ($current + $perside) > $page_count ? $page_count : $current + $perside;
        return compact(explode(' ', 'record_count perpage persection perside page_count current previous next'));
        /*
		return array(
			'record_count'=> $total,
			'perpage'	=> $perpage,
			'persection'=> $persection,
			'perside'	=> $perside,
			'page_count'=> $page_count,
			'current'	=> $current,
			'perside'	=> $perside,
			'previous'	=> $previous,
			'next'		=> $next,
		);
        */
    }
	/**
	 * 将数组中的变量替换到模板中
	 *
	 * @param string $t	模板
	 * @param array $aa	Hash数组
	 * @return string	返回结果
	 */
    protected function substitue($t, $aa)
    {
    	Crmlite_View_Helper_Pagination::$_params = $aa;
		return preg_replace_callback('/%\{(.*?)\}/i', create_function('$matches','return Crmlite_View_Helper_Pagination::$_params[$matches[1]];'), $t);
    }


    /**
     *
     *
     * @param array $param
     * @access protected
     * @return string
     */
    protected function _buildPaginBar($params = array())
    {
		$template = self::$styles[self::$style];
		$result = array_fill_keys(array_keys($template), '');
		$result['summary'] = self::substitue($template['summary'], $params);
		if($params['current'] > 1)
		{
			$params['_url'] = $this->view->UrlParams(array('page' => 1));
			$params['_text'] = 1;
			$result['first'] = self::substitue($template['first'], $params);
		}
		if($params['current'] > 2)
		{
			$params['_url'] = $this->view->UrlParams(array('page' => $params['current'] - 1));
			$params['_text'] = $params['current'] - 1;
			$result['previous'] = self::substitue($template['previous'], $params);
		}
		if($params['current'] < $params['page_count'] -1)
		{
			$params['_url'] = $this->view->UrlParams(array('page' => $params['current'] + 1));
			$params['_text'] = $params['current'] + 1;
			$result['next'] = self::substitue($template['next'], $params);
		}
		if($params['current'] < $params['page_count'])
		{
			$params['_url'] = $this->view->UrlParams(array('page' => $params['page_count']));
			$params['_text'] = $params['page_count'];
			$result['last'] = self::substitue($template['last'], $params);
		}
		$pages = array();
		foreach (range($params['previous'], $params['next']) as $i)
		{
			$params['_url'] = $this->view->UrlParams(array('page' => $i));
			$params['_text'] = $i;
			$pages[] = ($i == $params['current'])
					?self::substitue($template['current'], $params)
					:self::substitue($template['page'], $params);
		}
		$result['pages'] = implode($template['delimeter'], $pages);
        return self::substitue($template['result'], $result);
    }
}
